/* Ref: mbedtls/development/programs/pkey/pk_verify.c */
#include "mbedtls/build_info.h"
#include "mbedtls/error.h"
#include "mbedtls/md.h"
#include "mbedtls/pk.h"

#include "mbedtls/platform.h"

#include <stdio.h>
#include <string.h>

int main(int argc, char** argv)
{
    FILE* f;
    int ret = 1;
    size_t len_sign;
    int exit_code = MBEDTLS_EXIT_FAILURE;
    mbedtls_pk_context pk;
    unsigned char hash[32];
    unsigned char buf[MBEDTLS_PK_SIGNATURE_MAX_SIZE];

    mbedtls_pk_init(&pk);

    if (argc != 4) {
        printf("Usage:\n  %s <key_file> <raw_file> <sign_file>\n", argv[0]);
        goto exit;
    }

    printf("\n  . Reading public key from '%s'", argv[1]);
    fflush(stdout);
    if ((ret = mbedtls_pk_parse_public_keyfile(&pk, argv[1])) != 0) {
        printf(" failed\n  ! mbedtls_pk_parse_public_keyfile returned -0x%04x\n",
            (unsigned int)-ret);
        goto exit;
    }

    if ((f = fopen(argv[3], "rb")) == NULL) {
        printf("\n  ! Could not open %s\n\n", argv[3]);
        goto exit;
    }
    len_sign = fread(buf, 1, sizeof(buf), f);
    fclose(f);

    printf("\n  . Verifying the SHA-256 signature");
    fflush(stdout);

    if ((ret = mbedtls_md_file(
             mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
             argv[2], hash))
        != 0) {
        printf(" failed\n  ! Could not open or read %s\n\n", argv[2]);
        goto exit;
    }

    printf("\n  . MD(SHA-256):\n");
    for (int i = 0; i < 32; i++)
        printf("%s0x%02x %s", !i ? "\n" : "", hash[i], (i + 1) % 16 ? "" : "\n");
    if ((ret = mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, hash, 0,
             buf, len_sign))
        != 0) {
        printf(" failed\n  ! mbedtls_pk_verify returned -0x%04x\n", (unsigned int)-ret);
        goto exit;
    }

    printf("\n  . OK (the signature is valid)\n\n");

    exit_code = MBEDTLS_EXIT_SUCCESS;
exit:
    mbedtls_pk_free(&pk);
    mbedtls_exit(exit_code);
}
